import cgi, datetime, sys, os, json
import wsgiref.handlers

from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db, webapp
from google.appengine.api import users


class Plugin(db.Model):
    name = db.StringProperty()
    doc = db.TextProperty()
    category = db.CategoryProperty()
    rating = db.RatingProperty()

    def latest_revision(self):
        return Revision.all().filter("plugin = ", self).order("-date").get()

class Revision(db.Model):
    plugin = db.ReferenceProperty(Plugin)
    parent_rev = db.SelfReference()
    date = db.DateTimeProperty(auto_now_add=True)
    code = db.BlobProperty()
    objects = db.StringListProperty()

    @classmethod
    def all_by_plugin(cls, plugin):
        return cls.gql("WHERE plugin = :1", plugin)

    def date_string(self):
        return str(self.date.strftime("%d/%m/%y"))

    def as_dict(self):
        parent_rev = None if self.parent_rev is None else str(self.parent_rev.key())
        return {'plugin':str(self.plugin.key()),
                'parent_rev':parent_rev,
                'data':self.date_string(),
                'code':self.code}

class PluginHandler(webapp.RequestHandler):
    def get(self):
        # Get Variables
        r = self.request.get
        name,key = r("name"), r("key")

        result = {}                       # The Final output
        plugin_query = Plugin.all()       # The Final query-string


        if name:
            plugin_query.filter("WHERE name = :1",name)
        elif key:
            plugin_query = Plugin.get(key)
        
        for plugin in plugin_query:
            plug_obj = {}
            plug_obj['name']=str(plugin.name)
            plug_obj['doc']=str(plugin.doc)
            key = plugin.key()
            
            plug_obj['latest_code'] = ""
            plug_obj['latest_rev_id'] = ""
            
            latest_rev = plugin.latest_revision()            

            if latest_rev:
                plug_obj['latest_code'] = latest_rev.code
                plug_obj['latest_rev_id'] = str(latest_rev.key())
                plug_obj['latest_objects'] = map(str, latest_rev.objects)
            
            result[str(key)] = plug_obj

        self.response.out.write( json.dumps(result) )

    def put(self):
        
        body = json.loads(self.request.body)
        plugin = Plugin()
        plugin.name = str(body['name'])
        plugin.doc = str(body['doc'])
        plugin.put()
        
        root_rev = Revision()
        root_rev.plugin = plugin
        root_rev.code = str(body['code'])
        root_rev.objects = map(str, body['objects'])
        root_rev.put()
        
        self.response.out.write(json.dumps([str(plugin.key()), str(root_rev.key()) ]))


class RevisionHandler(webapp.RequestHandler):
    
    def get(self):
        r = self.request.get
        plugin_key, revision_key = r("plugin"), r("rev")
        
        if not revision_key and plugin_key:
            plugin = Plugin.get(plugin_key)
            
            revisions = list(Revision.all_by_plugin(plugin))
            data_dict = {}
            for rev in revisions:
                data_dict[str(rev.key())] = rev.as_dict()
            self.response.out.write(json.dumps(data_dict))
            return
        
        elif revision_key:
            rev = Revision.get(revision_key)
            data = {'date':rev.date_string(),
                    'code':rev.code}
            self.response.out.write(json.dumps(data))
        
        
    def put(self):
        body = json.loads(self.request.body)
        parent = str(body['parent'])
        plugin = str(body['plugin'])
        code = str(body['code'])
        objects = map(str, body['objects'])
        
        parent_rev = None
        
        if parent:
            parent_rev = Revision.get(parent)
            
        if plugin:
            plug = Plugin.get(plugin)
        else:
            plug = Plugin()
            plug.put()
        
        rev = Revision()
        rev.parent_rev = parent_rev
        rev.code = code
        rev.plugin = plug
        rev.objects = objects
        rev.put()
        
        self.response.out.write(json.dumps([str(plug.key()), str(rev.key())]))

    


application = webapp.WSGIApplication([
  ('/revision', RevisionHandler),
  ('/plugin', PluginHandler)
], debug=True)


def main():
  #wsgiref.handlers.CGIHandler().run(application)
  run_wsgi_app(application)

if __name__ == '__main__':
  main()